/**
 * Copyright (c) 2025   All rights reserved.
 * <p>
 * https://www.sdl.io
 * <p>
 * 版权所有，侵权必究！
 */

package io.sdl.controller;


import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import io.sdl.annotation.Login;
import io.sdl.common.utils.MessageUtils;
import io.sdl.common.utils.Result;
import io.sdl.common.validator.ValidatorUtils;
import io.sdl.dto.LoginDTO;
import io.sdl.entity.RoleUserEntity;
import io.sdl.entity.SysRoleEntity;
import io.sdl.entity.TokenEntity;
import io.sdl.entity.UserEntity;
import io.sdl.service.RoleUserService;
import io.sdl.service.SysRoleService;
import io.sdl.service.TokenService;
import io.sdl.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 登录接口
 *
 * @authorDc 1211734836@qq.com
 */
@RestController
@RequestMapping("/api")
@Tag(name = "登录接口")
@AllArgsConstructor
public class ApiLoginController {

	@Autowired
	private final UserService userService;

	@Autowired
	private final TokenService tokenService;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RoleUserService roleUserService;

	@Autowired
	private SysRoleService sysRoleService;

	@PostMapping("/loginByPhone")
	public Result<Map<String, Object>> loginByPhone(@RequestBody Map<String, String> params) {
		Map<String, Object> result = new HashMap<>();

		try {
			// 1. 获取session_key和openid
			String code = params.get("code");
			WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);

			// 2. 解密手机号
			String encryptedData = params.get("encryptedData");
			String iv = params.get("iv");
			WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(session.getSessionKey(), encryptedData, iv);
//            WxMaPhoneNumberInfo phoneNoInfo = WxMaPhoneNumberInfo.fromJson("13125170203");
			// 3. 返回结果
			result.put("success", true);
			result.put("phoneNumber", phoneNoInfo.getPhoneNumber());
//            result.put("openid", session.getOpenid());
			result.put("unionid", session.getUnionid());


			//用户注册/登录
			LoginDTO dto = new LoginDTO();
			dto.setOpenId(session.getOpenid());
			dto.setMobile(phoneNoInfo.getPhoneNumber());

			//表单校验
			ValidatorUtils.validateEntity(dto);

			UserEntity user = new UserEntity();
			user.setOpenId(dto.getOpenId());
			user.setMobile(dto.getMobile());
			user.setGender(dto.getGender());
			user.setCity(dto.getCity());
			user.setNickName(dto.getNickName());
			user.setAvatarUrl(dto.getAvatarUrl());
			//根据openid查询/新增用户
			Map<String, Object> orCreateUser = userService.findOrCreateUser(user);
			Map<String, Object> map = VerificationRole(orCreateUser.get("userId").toString());

			result.put("role", map.get("role"));
			result.put("token", orCreateUser.get("token"));
			result.put("roleYs", map.get("roleYs"));
			result.put("expire", orCreateUser.get("expire"));
		} catch (Exception e) {
			result.put("success", false);
			result.put("message", e.getMessage());
		}

		return new Result<Map<String, Object>>().ok(result);
	}


	@PostMapping("login")
	@Operation(summary = "登录")
	public Result<Map<String, Object>> login(@RequestBody LoginDTO dto) {
		//表单校验
		ValidatorUtils.validateEntity(dto);

		UserEntity user = new UserEntity();
		user.setOpenId(dto.getOpenId());
		user.setMobile(dto.getMobile());
		user.setGender(dto.getGender());
		user.setCity(dto.getCity());
		user.setNickName(dto.getNickName());
		user.setAvatarUrl(dto.getAvatarUrl());
		//根据openid查询/新增用户
		Map<String, Object> orCreateUser = userService.findOrCreateUser(user);
		Map<String, Object> map = VerificationRole(orCreateUser.get("userId").toString());
		orCreateUser.put("roleYs", map.get("roleYs"));
		orCreateUser.put("role", map.get("role"));
//        //用户登录
//        Map<String, Object> map = userService.login(dto);

		return new Result().ok(orCreateUser);
	}


	@PostMapping("logout")
	@Operation(summary = "退出")
	public Result logout(@RequestBody Map<String, String> params) {

		TokenEntity byToken = tokenService.getByToken(params.get("token"));
		if (byToken != null) {
			tokenService.expireToken(byToken.getUserId(), false);
		}

		return new Result();
	}


	//验证当前手机号是否已经选择过角色了
	public Map<String, Object> VerificationRole(String userId) {
		Map<String, Object> map = new HashMap<>();
		List<RoleUserEntity> roleUsersByRoleId = roleUserService.getRoleUsersByRoleId(Long.valueOf(userId));

		if (roleUsersByRoleId.size() > 0) {
			SysRoleEntity roleByRemark = sysRoleService.selectById(String.valueOf(roleUsersByRoleId.get(0).getRoleId()));
			map.put("roleYs", true);
			map.put("role", roleByRemark.getRemark());
			return map;
		} else {
			map.put("roleYs", false);
			return map;
		}
	}

	/*
	 * token检查
	 */
	@PostMapping("/checkToken")
	public Result checkToken(@RequestBody Map<String, String> params) {
		String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
		TokenEntity byToken = tokenService.checkToken(params.get("token"), format);
		HashMap<Object, Object> map = new HashMap<>();
		if (byToken != null) {
			//token续期
			tokenService.expireToken(byToken.getUserId(), true);
			List<RoleUserEntity> roleUserEntityList = roleUserService.getRoleUsersByRoleId(byToken.getUserId());
			//判断是否有角色
			if (roleUserEntityList.size() != 0) {

				SysRoleEntity sysRoleEntity = sysRoleService.selectById(roleUserEntityList.get(0).getRoleId());

				map.put("role", sysRoleEntity.getRemark());
				map.put("valid", true);
				return new Result().ok(map);
			} else {
				map.put("valid", false);
				return new Result().ok(map);
			}
		}
		map.put("valid", false);
		return new Result().ok(map);
	}


	/*
	 *账号密码登录
	 */
	@PostMapping("loginByPs")
	public Result passWordLogin(@RequestBody Map<String, String> params) {
		Map<String, Object> result = new HashMap<>();
		String s = params.get("mobile");
		String p = params.get("password");
		UserEntity byMobile = userService.getByMobile(s);

		if (byMobile == null) {
			result.put("success", false);
			result.put("failMsg", "手机号不存在");
			return new Result().ok(result);
		}
		try {
			//加密
			MessageDigest md = MessageDigest.getInstance("MD5");

			md.update(p.getBytes());

			String hashedPwd = new BigInteger(1, md.digest()).toString(16);

			UserEntity userEntity = userService.passWordLogin(s, hashedPwd);
			if (userEntity == null) {
				result.put("success", false);
				result.put("failMsg", "密码输入错误,请确认密码后重新输入");
				return new Result().ok(result);
			} else {
				Map<String, Object> orCreateUser = userService.findOrCreateUser(userEntity);

				Map<String, Object> map = VerificationRole(orCreateUser.get("userId").toString());
				result.put("role", map.get("role"));
				result.put("token", orCreateUser.get("token"));
				result.put("roleYs", map.get("roleYs"));
				result.put("mobile", byMobile.getMobile());
				result.put("expire", orCreateUser.get("expire"));
				result.put("success", true);
				return new Result().ok(result);
			}
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}

	}

}
